package assets;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;

import assets.loading.AssetLoader;
import assets.loading.LoadException;
import assets.unloading.AssetCacheReaper;
import core.Lunecy;
import util.collections.SoftCache;
import util.common.AbstractManager;

/**
 * Provides facilities for globally looking up resources.
 * @author Joel Rausch
 */
public class AssetManager extends AbstractManager {
	
	/** Soft cache of assets */
	private final SoftCache cache = new SoftCache(new AssetCacheReaper());
	
	/** Abstraction for loading assets from disk. */
	private final AssetLoader loader = new AssetLoader();

	public void startup() throws Exception {
	}

	public void shutdown() throws Exception {
	}
	
	/** Maintains asset cache. */
	public void update() {
		cache.maintain();
	}
	
	/**
	 * Return named asset, or null if it could not be loaded.
	 * @param name
	 * @return
	 */
	public Object load(String name) {
		// Get a hard reference
		Asset asset = (Asset) cache.get(name);
		if(asset == null) {
			try {
				asset = loader.loadAsset(name);
			} catch (LoadException e) {
				// TODO: Add log message here
				return null;
			}
			if(asset != null) {
				cache.put(name, asset);
			}
		}
		
		return asset;
	}
	
	/**
	 * Loads text from file.
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public String loadText(String path) throws IOException {
		  FileInputStream stream = new FileInputStream(new File(path));
		  try {
		    FileChannel fc = stream.getChannel();
		    MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
		    /* Instead of using default, pass in a decoder. */
		    return Charset.defaultCharset().decode(bb).toString();
		  }
		  finally {
		    stream.close();
		  }
	}
	
	/**
	 * Store the asset in the cache.
	 * @param name
	 * @param asset
	 */
	public void cacheAsset(String name, Asset asset) {
		if(name != null && asset != null) {
			cache.put(name, asset);
		}
	}
}
